#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTimerEvent>
#include "communication.h"
#include <QDebug>

#include <ctime>
#include <cstdlib>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    g_serial_port = new CSerialPort();
    connect(g_serial_port, &CSerialPort::update_serial_data, this, &MainWindow::on_update_serial_data);

//    time_id2s = startTimer(2000);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::timerEvent(QTimerEvent * ev)
{
    if(ev->timerId() == time_id2s)
    {
        qDebug() << "====== 2s";
        unsigned char array[13] = {0};
        array[0] = 0x01;
        array[1] = 0xff;
        array[2] = 0x00;

        uint32_t device_id = ui->lineEdit_device_id->text().toUInt();
        array[3] = (device_id | 0xff000000) >> 24;
        array[4] = (device_id | 0x00ff0000) >> 16;
        array[5] = (device_id | 0x0000ff00) >> 8;
        array[6] = (device_id | 0x000000ff);

        uint16_t left_count = ui->lineEdit_left_count->text().toUShort();
        array[7] = (left_count | 0xff00) >> 8;
        array[8] = (left_count | 0x00ff);

        uint8_t temprature = ui->lineEdit_temprature->text().toUShort();
        array[9] = temprature;

        uint8_t humidy = ui->lineEdit_humidy->text().toUShort();
        array[10] = humidy;

        uint8_t battery = ui->lineEdit_battery->text().toUShort();
        array[11] = battery;

        uint8_t charge_status = ui->lineEdit_charge_status->text().toUShort();
        array[12] = charge_status;

        SerialCMD(array,13);
    } else if(ev->timerId() == time_id200ms) {
        sendMeasureData(m_send_type);
    }
}

// 左闭右闭区间
int MainWindow::getRand(int min, int max) {
    return ( rand() % (max - min + 1) ) + min ;
}

void MainWindow::sendMeasureData(int type) {
    switch (type) {
    case 0x11:
    {
        srand(time(0));
        int ppb = getRand(80,100);
        int flow = getRand(30,60);

        unsigned char array[13] = {0};
        array[0] = 0x01;
        array[1] = 0xff;
        array[2] = 0x11;
        array[3] = (ppb & 0x0000ff00) >> 8;
        array[4] = (ppb & 0x000000ff);
        ui->textBrowser_send_rv->append("array[4]: " + QString::number(array[4]));
        array[5] = (flow & 0x0000ff00) >> 8;
        array[6] = (flow & 0x000000ff);
        SerialCMD(array,13);

        ui->textBrowser_send_rv->append("口呼气I: " + QString::number(ppb) +
                                      "  " + QString::number(flow) + "\r\n");
    }
        break;
    case 0x12:
    {
        srand(time(0));
        int ppb = getRand(80,100);
        int flow = getRand(45,55);

        unsigned char array[13] = {0};
        array[0] = 0x01;
        array[1] = 0xff;
        array[2] = 0x12;
        array[3] = (ppb & 0x0000ff00) >> 8;
        array[4] = (ppb & 0x000000ff);
        qDebug() << "array[4]: " + QString::number(array[4]) << endl;
        array[5] = (flow & 0x0000ff00) >> 8;
        array[6] = (flow & 0x000000ff);
        SerialCMD(array,13);

        m_send_count++;
        ui->textBrowser_send_rv->append("口呼气II(" + QString::number(m_send_count) + "): " +
                                        QString::number(ppb) +
                                        "  " + QString::number(flow) + "\r\n");

        if(m_send_count >= 200) {
            m_send_count = 0;
            m_send_type = 0x13;
        }
    }
        break;
    case 0x13:
    {
        int ppb = 99;
        unsigned char array[13] = {0};
        array[0] = 0x01;
        array[1] = 0xff;
        array[2] = 0x13;
        array[3] = (ppb & 0x0000ff00) >> 8;
        array[4] = (ppb & 0x000000ff);
        SerialCMD(array,13);

        ui->textBrowser_send_rv->append("================================\r\n");
        ui->textBrowser_send_rv->append("口呼气检测结果: " + QString::number(ppb) + "\r\n");
        ui->label_sample_status->setText("口呼气检测完成");

        killTimer(time_id200ms);
    }
        break;
    //////////////////////////////////////////////
    case 0x21:
    {
        srand(time(0));
        int ppb = getRand(80,100);
        int flow = getRand(45,55);

        unsigned char array[13] = {0};
        array[0] = 0x01;
        array[1] = 0xff;
        array[2] = 0x22;
        array[3] = (ppb & 0x0000ff00) >> 8;
        array[4] = (ppb & 0x000000ff);
        array[5] = (flow & 0x0000ff00) >> 8;
        array[6] = (flow & 0x000000ff);
        SerialCMD(array,13);
        m_send_count++;
        if(m_send_count >= 200) {
            killTimer(time_id200ms);
            m_send_count = 0;
            sendMeasureData(0x22);
            ui->label_sample_status->setText("离线检测完成");
        }
    }
        break;
    case 0x22:
    {
        int ppb = 99;
        unsigned char array[13] = {0};
        array[0] = 0x01;
        array[1] = 0xff;
        array[2] = 0x23;
        array[3] = (ppb & 0x0000ff00) >> 8;
        array[4] = (ppb & 0x000000ff);
        SerialCMD(array,13);
    }
        break;

    //////////////////////////////////////////////////////////////
    case 0x31:
    {
        srand(time(0));
        int ppb = getRand(80,100);
        int flow = getRand(30,60);

        unsigned char array[13] = {0};
        array[0] = 0x01;
        array[1] = 0xff;
        array[2] = 0x31;
        array[3] = (ppb & 0x0000ff00) >> 8;
        array[4] = (ppb & 0x000000ff);
        array[5] = (flow & 0x0000ff00) >> 8;
        array[6] = (flow & 0x000000ff);
        SerialCMD(array,13);
    }
        break;

    case 0x32:
    {
        srand(time(0));
        int ppb = getRand(80,100);
        int flow = getRand(45,55);

        unsigned char array[13] = {0};
        array[0] = 0x01;
        array[1] = 0xff;
        array[2] = 0x32;
        array[3] = (ppb & 0x0000ff00) >> 8;
        array[4] = (ppb & 0x000000ff);
        array[5] = (flow & 0x0000ff00) >> 8;
        array[6] = (flow & 0x000000ff);
        SerialCMD(array,13);
        m_send_count++;
        if(m_send_count >= 200) {
            killTimer(time_id200ms);
            m_send_count = 0;
            sendMeasureData(0x13);
            ui->label_sample_status->setText("口呼气检测完成");
        }
    }
        break;

    case 0x33:
    {
        int ppb = 99;
        unsigned char array[13] = {0};
        array[0] = 0x01;
        array[1] = 0xff;
        array[2] = 0x33;
        array[3] = (ppb & 0x0000ff00) >> 8;
        array[4] = (ppb & 0x000000ff);
        SerialCMD(array,13);
    }
        break;

    ///////////////////////////////////////////////////////////////
    case 0x41:
    {
        srand(time(0));
        int ppb = getRand(80,100);
        int flow = getRand(30,60);

        unsigned char array[13] = {0};
        array[0] = 0x01;
        array[1] = 0xff;
        array[2] = 0x41;
        array[3] = (ppb & 0x0000ff00) >> 8;
        array[4] = (ppb & 0x000000ff);
        array[5] = (flow & 0x0000ff00) >> 8;
        array[6] = (flow & 0x000000ff);
        SerialCMD(array,13);
    }
        break;
    case 0x42:
    {
        srand(time(0));
        int ppb = getRand(80,100);
        int flow = getRand(45,55);

        unsigned char array[13] = {0};
        array[0] = 0x01;
        array[1] = 0xff;
        array[2] = 0x42;
        array[3] = (ppb & 0x0000ff00) >> 8;
        array[4] = (ppb & 0x000000ff);
        array[5] = (flow & 0x0000ff00) >> 8;
        array[6] = (flow & 0x000000ff);
        SerialCMD(array,13);
        m_send_count++;
        if(m_send_count >= 200) {
            killTimer(time_id200ms);
            m_send_count = 0;
            sendMeasureData(0x43);
            ui->label_sample_status->setText("鼻呼气检测完成");
        }
    }
        break;
    default:
        break;
    }
}



void MainWindow::on_update_serial_data()
{
    unsigned char buf[256]={0};
    int size = 0;
    qDebug() << "0x update :" << endl;

    g_mutex_serial_update.lock();
    size = g_serial_size;
    memcpy(buf,g_serial_data,size);
    g_mutex_serial_update.unlock();

    if((buf[0] == 0x01)&&(buf[1]==0xff))
    {
        switch (buf[2])
        {
        case 0x01:
        {
            qDebug() << "0x01 :" << endl;
            uint16_t left_count = ui->lineEdit_left_count->text().toUShort() - 1;
            ui->lineEdit_left_count->setText(QString::number(left_count));
        }
        break;
        case 0x10:
        {
             qDebug() << "0x10 :" << endl;
             ui->textBrowser_send_rv->clear();
             ui->textBrowser_send_rv->setText("0x10:开始口呼气检测");
             measure_mode = MEASURE_MODE::FeNo;
             m_send_type = 0x11;
             ui->label_sample_status->setText("口呼气(I)");
             time_id200ms = startTimer(200);
        }
        break;
        case 0x11:
        {
            qDebug() << "0x11 :" << endl;
            measure_mode = MEASURE_MODE::FeNo;
            m_send_type = 0x12;
            ui->label_sample_status->setText("口呼气(II)");
            killTimer(time_id200ms);
            time_id200ms = startTimer(200);
            m_send_count = 0;
        }
            break;
        case 0x14:
        {
            killTimer(time_id200ms);
            time_id200ms = 0;
            m_send_count = 0;
            measure_mode = MEASURE_MODE::init;
            m_send_type = 0;
            ui->label_sample_status->setText("终止口呼气采样");

            ui->textBrowser_send_rv->append("================================\r\n");
            ui->textBrowser_send_rv->append("口呼气检测终止\r\n");
        }
        break;

        ///////////////////////////////
        case 0x20:
        {
            qDebug() << "0x20 :" << endl;
            measure_mode = MEASURE_MODE::sNO_OffLine;
            m_send_type = 0x21;
            ui->label_sample_status->setText("离线检测模式");
            time_id200ms = startTimer(200);
        }
        break;

        case 0x24:
        {
            killTimer(time_id200ms);
            time_id200ms = 0;
            m_send_count = 0;
            measure_mode = MEASURE_MODE::init;
            m_send_type = 0;
            ui->label_sample_status->setText("终止离线检测");
        }
        break;

        ///////////////////////////////
        case 0x30:
        {
             qDebug() << "0x30 :" << endl;
             measure_mode = MEASURE_MODE::CaNo;
             m_send_type = 0x31;
             ui->label_sample_status->setText("小气道(I)");
             time_id200ms = startTimer(200);
        }
        break;
        case 0x31:
        {
             qDebug() << "0x31 :" << endl;
             measure_mode = MEASURE_MODE::CaNo;
             m_send_type = 0x32;
             ui->label_sample_status->setText("小气道(II)");
             killTimer(time_id200ms);
             time_id200ms = startTimer(200);
        }
        break;
        case 0x34:
        {
            killTimer(time_id200ms);
            time_id200ms = 0;
            m_send_count = 0;
            measure_mode = MEASURE_MODE::init;
            m_send_type = 0;
            ui->label_sample_status->setText("终止小气道");
        }
        break;

        ///////////////////////////////////////////////////////////////
        case 0x40:
        {
             qDebug() << "0x40 :" << endl;
             measure_mode = MEASURE_MODE::FnNo;
             m_send_type = 0x41;
             ui->label_sample_status->setText("鼻呼气(I)");
             time_id200ms = startTimer(200);
        }
            break;
        case 0x41:
        {
             qDebug() << "0x40 :" << endl;
             measure_mode = MEASURE_MODE::FnNo;
             m_send_type = 0x42;
             killTimer(time_id200ms);
             ui->label_sample_status->setText("鼻呼气(II)");
             time_id200ms = startTimer(200);
        }
            break;
        case 0x44:
        {
            killTimer(time_id200ms);
            time_id200ms = 0;
            m_send_count = 0;
            measure_mode = MEASURE_MODE::init;
            m_send_type = 0;
            ui->label_sample_status->setText("终止鼻呼气");
        }
            break;

        default:
            break;
        }
    }
}


void MainWindow::SerialCMD(unsigned char*cmd,int size)
{
    g_com_size = 0;
    memcpy(g_com_buffer,cmd,size);
    g_com_size += size;

    unsigned short crc = CCommunication::do_crc(g_com_buffer,g_com_size);
    memcpy(&g_com_buffer[g_com_size],&crc,sizeof(unsigned short));
    g_com_size +=sizeof(unsigned short);

    g_com_buffer[g_com_size] = 0x02;
    g_com_size += 1;
    g_serial_port->SerialPort_Write(g_com_size,(char*)g_com_buffer);

    QString output = "";
    for(int i = 0; i < size+3; i++) {
        output.append(QString("0x%1 ").arg(g_com_buffer[i],2,16,QLatin1Char('0')));
    }

//    ui->textBrowser_send_rv->setText(ui->textBrowser_send_rv->toPlainText() + "\r\n" + output);
}

void MainWindow::on_pushButton_connect_serial_clicked(bool checked)
{
    qDebug() << "checked: " << checked;
    if(checked) {
        QString serial_name = ui->comboBox_serial_port_info->currentText();
        int ret = g_serial_port->SerialPort_Init(serial_name,9600);
        if(ret >= 0) {
            ui->label_connect_status->setText("连接成功：" + serial_name);
            ui->pushButton_connect_serial->setText("断开");
        } else {
            ui->label_connect_status->setText("连接失败：" + serial_name);
            ui->pushButton_connect_serial->setText("连接");
        }
    } else {
        g_serial_port->SerialPort_Close();
        ui->label_connect_status->setText("未连接");
        ui->pushButton_connect_serial->setText("连接");
    }
}

void MainWindow::on_pushButton_search_serial_clicked()
{
    //通过QSerialPortInfo查找可用串口
    ui->comboBox_serial_port_info->clear();
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        QString serial_name =  info.portName();
        ui->comboBox_serial_port_info->addItem(serial_name);
    }
}
